<template>
    <div class="schema-table">
        <el-table
            v-if="schema && schema.properties"
            v-loading="loading"
            :data="tableData"
            class="table">
            <template v-for="(schemaItem, key) in schema.properties">
                <el-table-column
                    v-if="schemaItem?.option?.visible !== false"
                    :key="key"
                    :label="schemaItem.label"
                    :prop="key"
                    v-bind="schemaItem.option"
                >
                </el-table-column>
            </template>
            <el-table-column
                v-if="buttons.length > 0"
                label="操作"
                fixed="right"
                :width="operationWidth"
            >
                <template #default="scope">
                    <el-button
                        v-for="(item, index) in buttons"
                        link
                        v-bind="item"
                        :key="index"
                        @click="operationHanler({ btnConfig: item, rowData: scope.row })"
                    >{{ item.label }}
                    </el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-row class="pagination">
            <el-pagination
                :current-page="currentPage"
                :page-size="pageSize"
                :page-sizes="[10, 20, 50, 100, 200]"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                >
            </el-pagination>
        </el-row>
    </div>
</template>

<script setup>
import { ref, toRefs, watch, computed, onMounted, nextTick } from 'vue';

import $curl from '$aegisCommon/curl.js';

const props = defineProps({
    /**
     * schema 配置
     * "type":  "object",
                "properties": {
                    "key": {
                        // ...标准schema配置
                        "type": "",  // 字段类型
                        "label": "", // 字段中文名
                        "tableOption": {
                            // "...elTableColumnConfig", 标准elTableColumnConfig配置
                            "visible": true //默认为true
                        }
                    }
                    // ...其他字段
                }
     */
    schema: Object,
    /**
     * api: 获取表格数据接口
     */
    api: String,
    /**
     * apiParams: 获取表格数据接口参数
     */
    apiParams: Object,
    /**
     * buttons: 表格按钮相关配置
     */
    buttons: Array
});

const { schema, api, apiParams, buttons } = toRefs(props);

const emit = defineEmits(["operate"]);

const operationWidth = computed(() => {
    return buttons?.value?.length > 0 ?buttons.value.reduce((pre, cur) => {
        return pre + cur.label.length * 18
    },50) : 50
});

const loading = ref(false);
const tableData = ref([]);
const currentPage = ref(1);
const pageSize = ref(50);
const total = ref(0);

onMounted(() => { 
    initData()
});

watch(() => [schema, api, apiParams], () => { 
    initData()
},{deep: true});
const initData = () => { 
    currentPage.value = 1
    pageSize.value = 50
    nextTick(async () => { 
        await loadTableData()
    })
};

let timerId = null
const loadTableData = async () => { 
    clearTimeout(timerId)
    timerId = setTimeout(async () => { 
        await fetchTableData()
        timerId = null
    }, 300)
};
const fetchTableData = async () => { 
    if (!api.value) return
    showLoading()

    const res = await $curl({
        method: 'get',
        url: `${api.value}/list`,
        query: {
            page: currentPage.value,
            size: pageSize.value,
            ...apiParams.value
        }
    })
    hideLoading()

    if (!res || !Array.isArray(res.data) || !res.success) {
        tableData.value = []
        total.value = 0
        return
    }

    tableData.value = buildTableData(res.data)
    
    total.value = res.metadata.total
};

const buildTableData = (listData) => { 
    if (!schema.value?.properties) {
        return listData
    }

    return listData.map(dataItem => { 
        for (const dKey in dataItem) { 
            const schemaItem = schema.value.properties[dKey]

            if (schemaItem?.option?.toFixed) { 
                dataItem[dKey] = dataItem[dKey].toFixed && dataItem[dKey].toFixed(schemaItem.option.toFixed)
            }
        }
        return dataItem
    })
};

const showLoading = () => { 
    loading.value = true
}
const hideLoading = () => { 
    loading.value = false
}

const operationHanler = ({ btnConfig, rowData}) => {
    emit('operate', { btnConfig, rowData})
}

const handleSizeChange = async function(size) {
    pageSize.value = size
    await loadTableData()
}

const handleCurrentChange = async function(current) {
    currentPage.value = current
    await loadTableData()

}

defineExpose({
    initData,
    loadTableData,
    hideLoading,
    showLoading,
})
</script>

<style lang="less" scoped>
.schema-table {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: auto;

    .table {
        flex: 1;
    }

    .pagination {
        margin: 10px 0;
        text-align: right;
    }
}
</style>